package outputviewer;

import guiobjects.IPaintedObject;

import java.awt.*;
import java.util.ArrayList;



/**
 * Draws an oval centered in the window.
 *
 * @author Robert C. Duvall
 */
@SuppressWarnings("serial")
public class Canvas extends Component
{
	private final int MAXFRAME = 60;
	
    private int myFrameRate;
    private int myFrameSum = 0;
    private int myFrameDifference = 1;
    private int myProduct = 1;
    private ArrayList<ArrayList<ArrayList<IPaintedObject>>> myGUIObjects = 
    	new ArrayList<ArrayList<ArrayList<IPaintedObject>>>();
    private int myFrameNumber = 0;
    public int[] myRelativeWidths;
    
    /**
     * Paint the contents of the applet.
     *
     * Never called by you directly, instead called by Java runtime
     * when area of screen covered by this container needs to be 
     * displayed (i.e., creation, uncovering, change in status)
     *
     * @param pen used to paint shape on the screen
     */
    public void paint (java.awt.Graphics pen)
    {
    	for (int i = 0; i < myRelativeWidths.length; i++)
    		myRelativeWidths[i] = Math.max(myRelativeWidths[i], 1);
    	if (myFrameNumber < 0)
    		myFrameNumber = myProduct - (-1 * myFrameNumber) % myProduct;
    	if (myFrameNumber >= myProduct)
    		myFrameNumber = myFrameNumber % myProduct;
		int[] trueAmount = new int[myRelativeWidths.length];
		int[] displaceAmount = new int[myRelativeWidths.length];
		int widthSum = 0;
		for (int i = 0; i < myRelativeWidths.length; i++)
			widthSum += myRelativeWidths[i];
		for (int i = 0; i < trueAmount.length; i++)
			trueAmount[i] = (myRelativeWidths[i] * getSize().width) / widthSum;
		int sum = 0;
		for (int i = 0; i < displaceAmount.length; i++)
		{
			displaceAmount[i] = sum;
			sum += trueAmount[i];
		}
    	for (int i = 0; i < myGUIObjects.size(); i++)
    	{
	        if (myGUIObjects.get(i).size() > 0)
	        {  
	            ArrayList<IPaintedObject> allFrames = myGUIObjects.get(i).get(0);
	            for (int k = 0; k < allFrames.size(); k++)
	            {
	            	allFrames.get(k).drawObject(pen, trueAmount[i], getSize().height, displaceAmount[i]);
	            }
	            if (myGUIObjects.get(i).size() > 1)
	            {
	            	int number = (myFrameNumber % (myGUIObjects.get(i).size() - 1)) + 1;
		            ArrayList<IPaintedObject> thisFrame = myGUIObjects.get(i).get(number);
		            for (int k = 0; k < thisFrame.size(); k++)
		            {
		            	thisFrame.get(k).drawObject(pen, trueAmount[i], getSize().height, displaceAmount[i]);
		            }
	            }
	        }
    	}
    	myFrameSum += myFrameRate;
    	if (myFrameSum >= MAXFRAME)
    	{
    		myFrameSum -= MAXFRAME;
            myFrameNumber += myFrameDifference;
    	}
    }
    public void setFrameRate(int rate)
    {
    	myFrameDifference = rate;
    }
    public void addAmount(int amount)
    {
    	myFrameNumber += amount;
    }
    public void takeScreenshot()
    {
    	SVGScreenshot screenThread = new SVGScreenshot(myGUIObjects, myRelativeWidths, (myFrameNumber % (myGUIObjects.get(0).size() - 1)) + 1);
    	screenThread.start();
    }
    /**
     * Called by each step of timer, multiple times per second.
     * 
     * This should update the state of the animated shapes by just
     * a little so they appear to move over time.
     */
	public void start (ArrayList<ArrayList<ArrayList<IPaintedObject>>> observations, int frameRate)
	{
		myFrameRate = frameRate;
		myGUIObjects = observations;
		for (int i = 0; i < observations.size(); i++)
			myProduct *= observations.get(i).size() - 1;
		myRelativeWidths = new int[observations.size()];
		for (int i = 0; i < observations.size(); i++)
			myRelativeWidths[i] = 100 / observations.size();
	}
}
